package com.even.camerarecoder.aac

import android.app.Application
import android.media.AudioFormat
import android.media.AudioRecord
import android.media.MediaRecorder
import android.os.Environment
import android.widget.Toast
import com.even.camerarecoder.App
import com.even.camerarecoder.MediaUtil
import com.evendai.loglibrary.Timber
import java.io.File
import java.io.FileOutputStream
import java.nio.ByteBuffer
import java.nio.channels.FileChannel

object AudioRecorder {

    private var mAACEncoderThread : AACEncoderThread? = null
    private var mAudioRecord : AudioRecord? = null
    private var mAACEncoder : AACEncoder? = null
    private var mIsInitialized = false
    private var mByteBuffer_1: ByteBuffer? = null
    private var mByteBuffer_2: ByteBuffer? = null
    private var useByteBuffer_1 = true

    private fun showToast(text: CharSequence, context: Application?) {
        context?.let { Toast.makeText(it, text, Toast.LENGTH_SHORT).show() }
    }

    fun startRecord(context: Application?) {
        if (mIsInitialized) return   // 已经初始化过了，无需重复初始化
        if (!MediaUtil.validateMicAvailability()) {
            showToast("录音失败，麦克风被占用", context)
            return
        }

        val audioSource = MediaRecorder.AudioSource.MIC
        val sampleRateInHz = 44100//8000//
        val channelConfig = AudioFormat.CHANNEL_IN_MONO
        val audioFormat = AudioFormat.ENCODING_PCM_16BIT
        val minBufferSize = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat)
        val audioRecord = AudioRecord(audioSource, sampleRateInHz, channelConfig, audioFormat, minBufferSize)
        this.mAudioRecord = audioRecord

        if (audioRecord.state != AudioRecord.STATE_INITIALIZED) {
            showToast("录音失败：初始化AudioRecord失败", context)
            Timber.fe("录音失败：初始化AudioRecord失败")
            return
        }

        mIsInitialized = true

        android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO)

        Timber.i("AudioRecord初始化完成")

        audioRecord.startRecording()

        val channelCount = if (channelConfig == AudioFormat.CHANNEL_IN_MONO) 1 else 2
        val aacEncoderThread = AACEncoderThread(sampleRateInHz, channelCount, minBufferSize).apply { start() }
        mAACEncoderThread = aacEncoderThread

        mByteBuffer_1 = ByteBuffer.allocateDirect(minBufferSize)
        mByteBuffer_2 = ByteBuffer.allocateDirect(minBufferSize)
        val byteBuffer = ByteBuffer.allocateDirect(minBufferSize)
        var start = 0L

        // 一秒钟音频大小为（单位是bit）：采样率 * 采样精度 * 通道数 = 总bit，换成字节需要除8
        // byteBuffer放进这里读之前需要clear，因为里面不会自动进行clear操作的
        while (mIsInitialized && audioRecord.read(byteBuffer, minBufferSize) > 0) {
            //start = System.nanoTime()
            if (useByteBuffer_1) {
                mByteBuffer_1!!.clear()
                mByteBuffer_1!!.put(byteBuffer)
                mByteBuffer_1!!.flip()
                aacEncoderThread.addPCMBytes(mByteBuffer_1!!)
            } else {
                mByteBuffer_2!!.clear()
                mByteBuffer_2!!.put(byteBuffer)
                mByteBuffer_2!!.flip()
                aacEncoderThread.addPCMBytes(mByteBuffer_2!!)
            }
            useByteBuffer_1 = !useByteBuffer_1

            byteBuffer.clear()
            //Timber.i("处理音频时间：${String .format("%.2f", (System.nanoTime() -  start) / 1000_000f)}")
        }
    }

    fun stopRecord() {
        try {
            if (mIsInitialized) { // 只有AudioRecord初始化之后才能调用stop函数
                mIsInitialized = false
                mAudioRecord?.stop()
            }

            mAudioRecord?.release()
            mAudioRecord = null

            mAACEncoderThread?.close()
            mAACEncoder = null
        } catch (e: Exception) {
            Timber.e(e, "别慌，正常停止AudioRecorder时出现的异常！")
        }
    }
}